///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef __BUOLA_IO_CFDPOLLER_H__
#define __BUOLA_IO_CFDPOLLER_H__

#include <buola/buola.h>

#include <map>
#include <buola/app/ceventloop.h>

namespace buola { namespace io {

///\addtogroup io
///@{

/////////////////////////////////////////////////////////////////////////////

/// fd poller

/// Objects of this class listen to events in file desccriptors
///
/////////////////////////////////////////////////////////////////////////////

class CFDPoller : public UUncopiable,public CLoopFunction
{
protected:
public:
//! \name constructor and destructor
//@{
    //! constructor

    //! creates a poller and doesn't link it to any event loop
    CFDPoller();

    //! constructor

    //! creates a poller and links it to the given event loop
    CFDPoller(CEventLoop &pLoop);

    //! destructor
    virtual ~CFDPoller();
//@}

public:
    //! adds a file-descriptor to listen to
    virtual void AddFDListener(CFDListener*,int pFD,ENotify pEvents,void *pClosure=nullptr,ENotifyOp pOp=ENotifyOp::SET)=0;

    //! removes all FD listeners for a certain file descriptor
    virtual void RemoveFDListeners(int pFD)=0;

    //! removes all FD listeners for a certain listener
    virtual void RemoveFDListeners(CFDListener *pListener)=0;
    
    //! removes all FD listeners from all pollers for a certain file descriptor
    static void RemoveAllFDListeners(int pFD);

    //! removes all FD listeners from all pollers for a certain listener
    static void RemoveAllFDListeners(CFDListener *pListener);
    
    //! waits for activity in the given set of file descriptors

    //! returns true if there was activity in any of them
    virtual bool WaitFDs(const chrono::nanoseconds &pDuration)=0;

private:
    virtual bool OnLoopFunction();

protected:
    //! mutex to lock when modifying file-descriptor list
    mutex mFDMutex;

    CEventLoop *mEventLoop;
};

///sets the main fd poller
///
///This can only be done before any call to get_main_fd_poller
void set_main_fd_poller(CFDPoller *pPoller);

///returns a reference to the default fd poller
CFDPoller &get_main_fd_poller();

///@}

/*namespace io*/ } /*namespace buola*/ }

#endif
